home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 7 / Amiga Format AFCD07 (Dec 1996, Issue 91).iso / serious / shareware / comms / internet / html-related / hsc / source / hsclib / idref.c < prev    next >
C/C++ Source or Header  |  1996-09-12  |  7KB  |  310 lines

  1. /*
  2.  * hsclib/idref.c
  3.  *
  4.  * functions for id-references
  5.  *
  6.  * Copyright (C) 1996  Thomas Aglassinger
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  *
  22.  * updated: 12-Sep-1996
  23.  * created: 12-Apr-1995
  24.  *
  25.  */
  26.  
  27. #include "hsclib/inc_base.h"
  28.  
  29. #include <stdarg.h>
  30.  
  31. #include "hscprj/document.h"
  32. #define NOEXTERN_HSCLIB_ID_H
  33. #include "hsclib/idref.h"
  34.  
  35. #if DEBUG_ID
  36. #define DIHP(x) if ( hp->debug ) x
  37. #define DI(x)   x
  38. #else
  39. #define DIHP(x)                 /* nufin */
  40. #define DI(x)                   /* nufin */
  41. #endif
  42.  
  43. /* hsc_msg_unknown_id: warning about unknown id-refrence */
  44. VOID hsc_msg_unknown_id(HSCPRC * hp, STRPTR filename, STRPTR id)
  45. {
  46.     if (filename)
  47.         hsc_message(hp, MSG_UNKN_ID, "unknown id `%s#%s'",
  48.                     filename, id);
  49.     else
  50.         hsc_message(hp, MSG_UNKN_ID, "unknown id %q", id);
  51. }
  52.  
  53. /*
  54.  *
  55.  * string-callbacks
  56.  *
  57.  */
  58.  
  59. /*
  60.  * del_string_entry
  61.  */
  62. VOID del_string_entry(APTR data)
  63. {
  64.     STRPTR s = (STRPTR) data;
  65.     ufreestr(s);
  66. }
  67.  
  68. /*
  69.  * new_string_entry
  70.  */
  71. STRPTR new_string_entry(STRPTR data)
  72. {
  73. #if 0
  74.     DI(fprintf(stderr, DHL "new string `%s'\n", data));
  75. #endif
  76.     return (strclone(data));
  77. }
  78.  
  79. /*
  80.  * cmp_string_entry
  81.  */
  82. int cmp_string_entry(APTR cmp_data, APTR lst_data)
  83. {
  84.     STRPTR s1 = (STRPTR) cmp_data;
  85.     STRPTR s2 = (STRPTR) lst_data;
  86.  
  87. #if DEBUG
  88.     if (!cmp_data)
  89.         panic("cmp_data = NULL");
  90.     if (!lst_data)
  91.         panic("lst_data = NULL");
  92. #endif
  93.  
  94.     if (!strcmp(s1, s2))
  95.         return (-1);
  96.     else
  97.         return (0);
  98. }
  99.  
  100. /* macros for local compare-callbacks */
  101. #define cmp_idname cmp_string_entry
  102. #define cmp_idref cmp_string_entry
  103. #define cmp_id_local cmp_string_entry
  104.  
  105. /*
  106.  *
  107.  * new- and del-methodes
  108.  *
  109.  */
  110.  
  111. #if 0
  112. /*
  113.  * del/new_id_local
  114.  */
  115.  
  116. /* del_id_local: remove local ID */
  117. VOID del_id_local(APTR data)
  118. {
  119.     IDLOCAL *id_local = (IDLOCAL *) data;
  120.  
  121.     ufreestr(id_local->name);
  122.     del_infilepos(id_local->fpos);
  123.     ufree(id_local);
  124. }
  125.  
  126. /* new_id_local: create new local id  */
  127. static IDLOCAL *new_id_local(STRPTR id, INFILEPOS * fpos)
  128. {
  129.     IDLOCAL *newid = (IDLOCAL *) umalloc(sizeof(IDLOCAL));
  130.  
  131.     newid->name = strclone(id);
  132.     newid->fpos = fpos;
  133.  
  134.     return (newid);
  135. }
  136.  
  137. /*
  138.  * hsc_add_id_local
  139.  */
  140. BOOL hsc_add_id_local(HSCPRC * hp, STRPTR id)
  141. {
  142.     INFILEPOS *fpos = new_infilepos(hp->inpf);
  143.  
  144.     DIHP(fprintf(stderr, DHL "add local id `%s' at `%s' (%lu,%lu)\n",
  145.                  id, ifp_get_fname(fpos),
  146.                  ifp_get_y(fpos), ifp_get_x(fpos)));
  147.  
  148.     /* TODO: check for duplicate ID */
  149.     app_dlnode(hp->id_local, (APTR) new_id_local(id, fpos));
  150.  
  151.     return (TRUE);
  152. }
  153.  
  154. #endif
  155.  
  156. /*
  157.  * del/new_idref
  158.  */
  159.  
  160. /* del_idref: remove referenced id */
  161. VOID del_idref(APTR data)
  162. {
  163.     IDREF *idref = (IDREF *) data;
  164.  
  165.     ufreestr(idref->name);
  166.     del_infilepos(idref->fpos);
  167.     ufree(idref);
  168. }
  169.  
  170. /* new_id_local: create new reference to local id  */
  171. static IDREF *new_idref(STRPTR id, INFILEPOS * fpos)
  172. {
  173.     IDREF *newid = (IDREF *) umalloc(sizeof(IDREF));
  174.  
  175.     newid->name = strclone(id);
  176.     newid->fpos = fpos;
  177.  
  178.     return (newid);
  179. }
  180.  
  181. VOID prt_idref(FILE * stream, APTR data)
  182. {
  183.     IDREF *idref = (IDREF *) data;
  184.     INFILEPOS *fpos = idref->fpos;
  185.  
  186.     fprintf(stream, "`%s' at (%lu,%lu)\n",
  187.             idref->name, ifp_get_y(fpos), ifp_get_x(fpos));
  188. }
  189.  
  190. /*
  191.  * add_local_iddef
  192.  *
  193.  * define a new local ID that can be refered to
  194.  */
  195. BOOL add_local_iddef(HSCPRC * hp, STRPTR id)
  196. {
  197.     INFILEPOS *fpos = new_infilepos(hp->inpf);
  198.     HSCIDD *iddef = find_iddef(hp->project->document, id);
  199.  
  200.     DIHP(fprintf(stderr, DHL "add ref to id `%s' at `%s' (%lu,%lu)\n",
  201.                  id, ifp_get_fname(fpos),
  202.                  ifp_get_y(fpos), ifp_get_x(fpos)));
  203.  
  204.     /* check for duplicate definition */
  205.  
  206.     if (iddef) {
  207.         /* duplicate definition */
  208.         DIHP(fprintf(stderr, DHL "    duplicate definition\n"));
  209.  
  210.         hsc_message(hp, MSG_REDEFINE_ID,
  211.                     "local id %q already declared", id);
  212.  
  213.         set_infilepos(hp->inpf, iddef->fpos);
  214.         hsc_message(hp, MSG_REDEFINE_ID,
  215.                     "(location of previous declaration)");
  216.  
  217.         set_infilepos(hp->inpf, fpos);
  218.         del_infilepos(fpos);
  219.     } else {
  220.         /* remember new local id */
  221.         iddef = app_iddef(hp->project->document, id);
  222.         iddef->caller = fpos2caller(fpos);
  223.         iddef->fpos = fpos;
  224.  
  225.         DIHP(fprintf(stderr, DHL "    append to local iddefs\n"));
  226.     }
  227.  
  228.     return (TRUE);
  229. }
  230.  
  231. /*
  232.  * check_id_local
  233.  *
  234.  * append id to idref-list so it as checked when
  235.  * check_all_local_idref() is called
  236.  */
  237. VOID add_local_idref(HSCPRC * hp, STRPTR id)
  238. {
  239.     INFILEPOS *fpos = new_infilepos(hp->inpf);
  240.  
  241.     DIHP(fprintf(stderr, DHL "  check id: `#%s' (local)\n", id));
  242.     DIHP(fprintf(stderr, DHL "    append to idref\n"));
  243.     app_dlnode(hp->idrefs, new_idref(id, fpos));
  244. }
  245.  
  246. /*
  247.  * check_local_idref
  248.  */
  249. static BOOL check_local_idref(HSCPRC * hp, IDREF * idref)
  250. {
  251.     HSCIDD *iddef = find_iddef(hp->project->document, idref->name);
  252.     BOOL found = FALSE;
  253.  
  254.     if (iddef) {
  255.  
  256.         found = TRUE;
  257.         DIHP(fprintf(stderr, DHL " local id ok: `%s'\n", idref->name));
  258.  
  259.     } else {
  260.  
  261.         DIHP( {
  262.              INFILEPOS * fpos = idref->fpos;
  263.              fprintf(stderr, DHL " local id unknown: `%s' (%lu,%lu)\n",
  264.                      idref->name, ifp_get_y(fpos), ifp_get_x(fpos));
  265.              }
  266.         );
  267.  
  268.         set_infilepos(hp->inpf, idref->fpos);
  269.         hsc_msg_unknown_id(hp, NULL, idref->name);
  270.  
  271.     }
  272.  
  273.     return (found);
  274. }
  275.  
  276. /*
  277.  * check_all_local_idref
  278.  */
  279. BOOL check_all_local_idref(HSCPRC * hp)
  280. {
  281.     BOOL ok = TRUE;
  282.     DLNODE *nd = NULL;
  283.     INFILEPOS *infpos = new_infilepos(hp->inpf);
  284.  
  285.     DIHP(fprintf(stderr, DHL "check local IDs\n"));
  286.  
  287.     DIHP( {
  288.  
  289.          fprintf(stderr, DHL " local IDs defined:\n");
  290.          fprintf_dllist(stderr, hp->project->document->iddefs, prt_iddef);
  291.          fprintf(stderr, DHL " local IDs referenced:\n");
  292.          fprintf_dllist(stderr, hp->idrefs, prt_idref);
  293.  
  294.          }
  295.     );
  296.  
  297.     nd = dll_first(hp->idrefs);
  298.     while (nd) {
  299.  
  300.         check_local_idref(hp, ((IDREF *) nd->data));
  301.         nd = dln_next(nd);
  302.     }
  303.  
  304.     set_infilepos(hp->inpf, infpos);
  305.     del_infilepos(infpos);
  306.  
  307.     return (ok);
  308. }
  309.  
  310.